package org.lib.authservice;

import javax.sql.DataSource;

import org.lib.authservice.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

@SpringBootApplication
// 启动资源服务
@EnableResourceServer
public class AuthServiceApplication {

	@Autowired
	@Qualifier(value = "dataSource")
	private DataSource dataSource;
	
	public static void main(String[] args) {
		SpringApplication.run(AuthServiceApplication.class, args);
	}

	/**
	 * 授权服务配置
	 * client信息，2个，存放在内存中
	 * token信息，需要存入MySQL，还需要建表
	 * @author ben
	 * @date 2021-10-21 16:43:54 CST
	 */
	@Configuration
	@EnableAuthorizationServer
	protected class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
		
		// 方式1：token存 内存
//		private InMemoryTokenStore tokenStore = new InMemoryTokenStore();
		// 方式2：token存 MySQL
		JdbcTokenStore tokenStore = new JdbcTokenStore(dataSource);
		
		@Autowired
		@Qualifier("authenticationManagerBean")
		private AuthenticationManager authenticationManager;
		
		@Autowired
		private UserService userService;
		
		// 重写 AuthorizationServerConfigurerAdapter 的3个方法

		@Override
		public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
			security
				.tokenKeyAccess("permitAll()")
				.checkTokenAccess("isAuthenticated")
				.allowFormAuthenticationForClients()
				// 过时的 NoOpPasswordEncoder 怎么替换呢！TODO
				.passwordEncoder(NoOpPasswordEncoder.getInstance());
		}

		@Override
		public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
			// clients 暂时存储到内存，后续改造为使用 数据库 TODO
			clients.inMemory()
				// 1、浏览器
				.withClient("browser")
					// 授权类型
					.authorizedGrantTypes("refresh_token", "password")
					.scopes("ui")
					.and()
				// 2、服务：service-hi
				.withClient("service-hi")
					.secret("111")
					.authorizedGrantTypes("client_credentials", "refresh_token", "password")
					.scopes("server");
		}

		@Override
		public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
			endpoints
				.tokenStore(tokenStore)
				.authenticationManager(authenticationManager)
				.userDetailsService(userService);
		}
		
	}
}
